﻿using DtuService;
using System;
using System.Collections.Generic;
using NetCommand;
using SuperSocket.SocketBase;

namespace DtuService
{
    public struct CMD_PACK
    {
        public byte[] NetBtyeMessage;
        public object MessageHandler;
    }
    class MessageServer : IServer
    {
        private Queue<CMD_PACK> cmdList1 = new Queue<CMD_PACK>();
        private Queue<CMD_PACK> cmdList2 = new Queue<CMD_PACK>();
        private int currentWriteCmdList = 1;
        private int currentReadCmdList = 2;
        private static object msgOperationLock1 = new object();

        public void Init()
        {     
        }

        public void InsertMessage(object owner, byte[] bMessage)
        {
            lock (msgOperationLock1)
            {
                if (currentWriteCmdList == 1)
                {
                    CMD_PACK pack;
                    pack.MessageHandler = owner;
                    pack.NetBtyeMessage = bMessage;
                    cmdList1.Enqueue(pack);
                }

                else
                {

                    CMD_PACK pack;
                    pack.MessageHandler = owner;
                    pack.NetBtyeMessage = bMessage;
                    cmdList2.Enqueue(pack);
                }
            }
        }

        public void ShutDown()
        {
            cmdList1.Clear();
            cmdList2.Clear();
        }

        private void descMassage(CMD_PACK pack)
        {
            if (pack.NetBtyeMessage == null)
            {
                return;
            }
            if (pack.NetBtyeMessage.Length == 0)
            {
                return;
            }
            if (pack.NetBtyeMessage[0] != NetCommon.D2S_HEADER_CODE && pack.NetBtyeMessage[0] != NetCommon.C2S_HEADER_CODE)
            {
                return;
            }
            if (pack.MessageHandler == null)
            {
                Debug.Log("没有处理载体");
                return;
            }
            ushort errorCode = 0;

            NetCommand.NetCommand msg = NetCommand.CommandTranslator.Instance.DecodeMessage(ref pack.NetBtyeMessage, ref errorCode);
            if (msg == null)
            {
                Debug.Error("消息错误");
                return;
            }
            switchCommand(pack, errorCode, msg);
        }

        private void switchCommand(CMD_PACK pack, ushort errorCode, NetCommand.NetCommand msg)
        {
            //Debug.Log(msg.ToString());
            switch (errorCode)
            {
                case NetCode.NO_ERROR:
                    {
                        handleMsg(pack, msg);
                    }
                    break;
                case NetCode.CRC_ERROR:
                    {
                        Debug.Error("CRC 验证失败");
                    }
                    break;
                case NetCode.CMD_TYPE_ERROR:
                case NetCode.CMD_FRONT_CODE_ERROR:
                    break;
                case NetCode.CMD_LENGTH_ERROR:
                    {
                        Debug.Error("消息长度错误");
                    }
                    break;
                default:
                    break;
            }
            if (pack.NetBtyeMessage != null && pack.NetBtyeMessage.Length > 0)
            {
                descMassage(pack);
            }
        }

        private static void handleMsg(CMD_PACK pack, NetCommand.NetCommand msg)
        {
            ByteSession tcp = (ByteSession)pack.MessageHandler;
            Client client = null;
            if (tcp.ClientInstance == null)
            {
                client = new Device(tcp);
                tcp.ClientInstance = client;
                client.ProcessMessage(msg);
            }
            else
            {
                client = (Client)tcp.ClientInstance;
                client.ProcessMessage(msg);
            }
        }

        public void Tick(float deltaTime)
        {
            if (cmdList2.Count == 0 && cmdList1.Count == 0)
            {
                return;
            }
            lock (msgOperationLock1)
            {
                try
                {
                    if (currentWriteCmdList == 1)
                    {
                        foreach (CMD_PACK pack in cmdList2)
                        {
                            descMassage(pack);
                        }
                        cmdList2.Clear();
                        currentWriteCmdList = 2;
                    }
                    else if (currentWriteCmdList == 2)
                    {
                        foreach (CMD_PACK pack in cmdList1)
                        {
                            descMassage(pack);
                        }
                        cmdList1.Clear();
                        currentWriteCmdList = 1;
                    }
                }
                catch (Exception ex)
                {
                    Debug.Error(ex.ToString());
                }
            }
            // end of lock
        }
        // end of tick

    }
}
